//
// Created by 32827 on 2023/11/23.
//
#include "yz_time.h"
volatile YZ_TIME SystemOSTime= {0,0};
void yz_time_handler(YZF_GLOBAL_INDEX index){
    if(yzf_sys_tick_countFlag()) {
        SystemOSTime.SYStemOSTime += YZ_SystemOSTimeEXACT;
        if (SystemOSTime.SYStemOSTime >= YZ_SystemOSTimeM_SIZE) {
            SystemOSTime.SYStemOSTime %= YZ_SystemOSTimeM_SIZE;
            SystemOSTime.SYStemOSTimeM += 1;
        }
    }
}
void yz_time_handler_tim(YZF_GLOBAL_INDEX index){
    if(yzf_tim_get_update_interrupt_flag(TIM1,YZF_TRUE)) {
        SystemOSTime.SYStemOSTime += YZ_SystemOSTimeEXACT;
        if (SystemOSTime.SYStemOSTime >= YZ_SystemOSTimeM_SIZE) {
            SystemOSTime.SYStemOSTime %= YZ_SystemOSTimeM_SIZE;
            SystemOSTime.SYStemOSTimeM += 1;
        }
    }
}
void yz_time_init(uint32_t system_clock){
    yzf_nvic_irq_enable(SysTick_IRQn);
    yzf_nvic_irq_set_priority(SysTick_IRQn,0b01000000);
    yz_int_set_SysTick(yz_time_handler,YZF_GLOBAL_SHEET_ERROR_INDEX);
    yzf_sys_tick_interrupt_enable();
    yzf_sys_tick_source_clk();
    yzf_sys_tick_set_var(0);
    yzf_sys_tick_load(system_clock/1000/1000*YZ_SystemOSTimeEXACT);
    yzf_sys_tick_enable();
}
void yz_time_init_tim(uint32_t system_clock){
    yzf_tim_disable(TIM1);
    yzf_nvic_irq_enable(TIM1_UP_TIM10_IRQn);
    yzf_nvic_irq_set_priority(TIM1_UP_TIM10_IRQn,0b01000000);
    yz_int_set_TIM1(yz_time_handler_tim,YZF_GLOBAL_SHEET_ERROR_INDEX);
    yzf_tim_open_clock(TIM1);
    yzf_tim_update_source(TIM1,1);
    yzf_tim_update_event_enable(TIM1);
    yzf_tim_set_cnt(TIM1,0);
    TIM1->DIER |= TIM_DIER_UIE;
    yzf_tim_set_prescaler(TIM1,0);
    yzf_tim_set_auto_reload_number(TIM1,system_clock/1000/1000*YZ_SystemOSTimeEXACT);
    yzf_tim_enable(TIM1);
}
YZ_TIME * yz_time_get(){
    return (YZ_TIME *)&SystemOSTime;
}
uint32_t yz_time_get_us(){
    return SystemOSTime.SYStemOSTime;
}
uint32_t yz_time_get_min(){
    return SystemOSTime.SYStemOSTimeM;
}
#if YZ_USE_TICK_WITH_HAL
void yz_time_delay_ms(uint32_t data){
    HAL_Delay(data);
}
#else
void yz_time_delay_us(uint32_t us){
    uint32_t start_us=SystemOSTime.SYStemOSTime;
    uint32_t end_min=SystemOSTime.SYStemOSTimeM;
    uint32_t end_us=SystemOSTime.SYStemOSTime+us;
    if (start_us+us>=60000000){
        end_us=start_us+us-60000000;
        end_min+=1;
    }
    while (SystemOSTime.SYStemOSTimeM<end_min||SystemOSTime.SYStemOSTime<end_us){
        __asm__("nop"); //阻塞
    }
}
void yz_time_delay_ms(uint32_t ms){
    uint32_t min=ms/(60*1000);
    for(uint32_t i=0;i<min;i++){
        yz_time_delay_us(60*1000*000);
    }
    yz_time_delay_us((ms%(60*1000))*1000);
}
void yz_time_delay_s(uint32_t s){
    uint32_t min=s/60;
    for(uint32_t i=0;i<min;i++){
        yz_time_delay_us(60*1000*000);
    }
    yz_time_delay_us((s%60)*1000*1000);
}
#endif